#include "nvs_utils.h"
#define NVS_UTILS_TAG "NVS_UTILS"
#include "esp_log.h"
static  bool nvs_initialized=false;
// 初始化 NVS
esp_err_t nvs_utils_init() {
    if (nvs_initialized){
        return ESP_OK;
    }
    ESP_LOGI(NVS_UTILS_TAG, "NVS namespace: %s", NVS_NAMESPACE_CONFIG);
    esp_err_t err;
    err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_LOGW(NVS_UTILS_TAG, "NVS initialization failed, erasing and retrying...");
        err = nvs_flash_erase();
        if (err != ESP_OK) {
            ESP_LOGE(NVS_UTILS_TAG, "Failed to erase NVS flash: %s", esp_err_to_name(err));
            return err;
        }
        err = nvs_flash_init();
    }
    if (err != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Failed to initialize NVS flash: %s", esp_err_to_name(err));
        return err;
    }

    nvs_handle_t nvs_handle;
    ESP_LOGI(NVS_UTILS_TAG, "Attempting to open NVS namespace: %s", NVS_NAMESPACE_CONFIG);
    // 尝试以只读模式打开 NVS 命名空间
    err = nvs_open(NVS_NAMESPACE_CONFIG, NVS_READONLY, &nvs_handle);
    if (err == ESP_ERR_NVS_NOT_FOUND) {
        // 命名空间不存在，以读写模式打开来创建它
        ESP_LOGI("NVS", "Namespace not found. Creating it...");
        err = nvs_open(NVS_NAMESPACE_CONFIG, NVS_READWRITE, &nvs_handle);
        if (err != ESP_OK) {
            ESP_LOGE("NVS", "Failed to open NVS namespace for writing: %s", esp_err_to_name(err));
            return err;
        }
        // 在这里可以初始化一些默认值
        err = nvs_set_i32(nvs_handle, "default_value", 0);
        if (err != ESP_OK) {
            ESP_LOGE("NVS", "Failed to set default value: %s", esp_err_to_name(err));
        }
        err = nvs_commit(nvs_handle);
        if (err != ESP_OK) {
            ESP_LOGE("NVS", "Failed to commit changes: %s", esp_err_to_name(err));
        }
    } else if (err != ESP_OK) {
        ESP_LOGE("NVS", "Failed to open NVS namespace: %s", esp_err_to_name(err));
        return err;
    }
    nvs_initialized = true;
    nvs_close(nvs_handle); // 打开后记得关闭句柄
    ESP_LOGI(NVS_UTILS_TAG, "NVS handle opened successfully");
    return ESP_OK;
}

// 封装读取字符串的函数
esp_err_t read_nvs_str(nvs_handle_t handle, const char* key, char* value, size_t max_len) {
    size_t required_size;
    esp_err_t err = nvs_get_str(handle, key, NULL, &required_size);
    if (err == ESP_OK) {
        if (required_size > max_len) {
            ESP_LOGE(NVS_UTILS_TAG, "Value for %s is too long!", key);
            return ESP_ERR_INVALID_SIZE;
        }
        err = nvs_get_str(handle, key, value, &required_size);
    }
    if (err == ESP_ERR_NVS_NOT_FOUND) {
        // 当键不存在时，不记录错误日志，设置为空字符串
        value[0] = '\0';
        err = ESP_OK;
    } else if (err != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error reading %s from NVS: %s", key, esp_err_to_name(err));
        value[0] = '\0';
    }
    return err;
}

// 封装读取 32 位无符号整数的函数
esp_err_t read_nvs_u32(nvs_handle_t handle, const char* key, uint32_t* value) {
    esp_err_t err = nvs_get_u32(handle, key, value);
    if (err == ESP_ERR_NVS_NOT_FOUND) {
        // 当键不存在时，设置为默认值 0，不记录错误日志
        *value = 0;
        err = ESP_OK;
    } else if (err != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error reading %s from NVS: %s", key, esp_err_to_name(err));
        *value = 0; // 设置为默认值 0
    }
    return err;
}

// 封装读取 64 位无符号整数的函数
esp_err_t read_nvs_u64(nvs_handle_t handle, const char* key, uint64_t* value) {
    esp_err_t err = nvs_get_u64(handle, key, value);
    if (err == ESP_ERR_NVS_NOT_FOUND) {
        // 当键不存在时，设置为默认值 0，不记录错误日志
        *value = 0;
        err = ESP_OK;
    } else if (err != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error reading %s from NVS: %s", key, esp_err_to_name(err));
        *value = 0; // 设置为默认值 0
    }
    return err;
}

// 封装读取 8 位有符号整数的函数
esp_err_t read_nvs_i8(nvs_handle_t handle, const char* key, int8_t* value) {
    esp_err_t err = nvs_get_i8(handle, key, value);
    if (err == ESP_ERR_NVS_NOT_FOUND) {
        // 当键不存在时，设置为默认值 0，不记录错误日志
        *value = 0;
        err = ESP_OK;
    } else if (err != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error reading %s from NVS: %s", key, esp_err_to_name(err));
        *value = 0; // 设置为默认值 0
    }
    return err;
}

// 封装设置字符串的函数
esp_err_t set_str(nvs_handle_t handle, const char* key, const char* value) {
    esp_err_t res = nvs_set_str(handle, key, value);
    if (res != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error (%s) setting %s!", esp_err_to_name(res), key);
        nvs_close(handle);
    }
    return res;
}

// 封装设置 32 位无符号整数的函数
esp_err_t set_u32(nvs_handle_t handle, const char* key, uint32_t value) {
    esp_err_t res = nvs_set_u32(handle, key, value);
    if (res != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error (%s) setting %s!", esp_err_to_name(res), key);
        nvs_close(handle);
    }
    return res;
}

// 封装设置 64 位无符号整数的函数
esp_err_t set_u64(nvs_handle_t handle, const char* key, uint64_t value) {
    esp_err_t res = nvs_set_u64(handle, key, value);
    if (res != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error (%s) setting %s!", esp_err_to_name(res), key);
        nvs_close(handle);
    }
    return res;
}

// 封装设置 8 位有符号整数的函数
esp_err_t set_i8(nvs_handle_t handle, const char* key, int8_t value) {
    esp_err_t res = nvs_set_i8(handle, key, value);
    if (res != ESP_OK) {
        ESP_LOGE(NVS_UTILS_TAG, "Error (%s) setting %s!", esp_err_to_name(res), key);
        nvs_close(handle);
    }
    return res;
}